package cn.jobstart.common.algorithm;


import cn.jobstart.common.SkMap;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @author sunke
 * @version 1.0
 * @Description
 * @date 2023-11-01 14:41
 */
public class AlgorithmUtil {


    /**
     * 欧式距离
     * 相似度，范围：[0,1]，值越大，说明 d 越小，也就是距离越近，则相似度越大。
     *
     * @param oneMap
     * @param twoMap
     * @return
     */
    public static double compare(Map<String, String> oneMap, Map<String, String> twoMap) {

        double result = 0;
        for (String key : oneMap.keySet()) {
            result += Math.pow(oneMap.get(key).hashCode() - twoMap.get(key).hashCode(), 2);

        }
        result = Math.sqrt(result);


        return 1 / (1 + result);

    }

    public static double getSimilarity(String str1) {

        String str2 = "经济";

        int distance = StringUtils.getLevenshteinDistance(str1, str2);
        int maxLen = Math.max(str1.length(), str2.length());
        double similarity = (maxLen - distance) / (double) maxLen;

        return similarity;

    }

    public static double getSimilarity(String str1, String str2) {


        int distance = StringUtils.getLevenshteinDistance(str1, str2);
        int maxLen = Math.max(str1.length(), str2.length());
        double similarity = (maxLen - distance) / (double) maxLen;

        return similarity;

    }


    /**
     * 余弦相似度公式 范围：[-1,1]，值越大，说明夹角越大，两点相距就越远，相似度就越小。
     *
     * @param oneMap
     * @param twoMap
     * @return
     */
    public static double cosineSimilarity(Map<String, String> oneMap, Map<String, String> twoMap) {


        // 计算两个向量的点积
        double dotProduct = 0;
        for (String key : oneMap.keySet()) {
            if (twoMap.containsKey(key)) {
                dotProduct += oneMap.get(key).hashCode() * twoMap.get(key).hashCode();


            }
        }


        // 计算向量A的模
        double magnitudeA = 0;
        for (String value : oneMap.values()) {
            magnitudeA += Math.pow(value.hashCode(), 2);

        }
        magnitudeA = Math.sqrt(magnitudeA);

        // 计算向量B的模
        double magnitudeB = 0;
        for (String value : twoMap.values()) {
            magnitudeB += Math.pow(value.hashCode(), 2);

        }
        magnitudeB = Math.sqrt(magnitudeB);

        // 计算余弦相似度
        return dotProduct / (magnitudeA * magnitudeB);
    }


    public static void main(String[] args) {


        Map<String, String> toComparedMap = SkMap.getInstance();
        toComparedMap.put("name", "张");
        toComparedMap.put("sex", "男");
        toComparedMap.put("school", "浙江大学");
        toComparedMap.put("major", "经济学");
        toComparedMap.put("school_date_start", "2012-07");
        toComparedMap.put("school_date_end", "2016-05");
        toComparedMap.put("company", "雅戈尔集团");
        toComparedMap.put("company_date_start", "2016-07");
        toComparedMap.put("company_data_end", "2018-07");


        Map<String, String> dataMap = SkMap.getInstance();
        dataMap.put("name", "张");
        dataMap.put("sex", "男");
        dataMap.put("school", "浙江大学");
        dataMap.put("major", "计算机");
        dataMap.put("school_date_start", "2012-07");
        dataMap.put("school_date_end", "2016-05");
        dataMap.put("company", "雅戈尔集团");
        dataMap.put("company_date_start", "2016-07");
        dataMap.put("company_data_end", "2018-07");


        Map<String, String> dataMap1 = SkMap.getInstance();
        dataMap1.put("name", "张");
        dataMap1.put("sex", "男");
        dataMap1.put("school", "宁波大学");
        dataMap1.put("major", "经济学");
        dataMap1.put("school_date_start", "2012-07");
        dataMap1.put("school_date_end", "2016-05");
        dataMap1.put("company", "雅戈尔集团");
        dataMap1.put("company_date_start", "2016-07");
        dataMap1.put("company_data_end", "2018-07");


        BigDecimal a = new BigDecimal(cosineSimilarity(toComparedMap, dataMap));
        BigDecimal b = new BigDecimal(cosineSimilarity(toComparedMap, dataMap1));


        System.out.println(a.toPlainString());
        System.out.println(b.toPlainString());
        System.out.println(a.compareTo(b));
        System.out.println();

       /* a = new BigDecimal(compare(toComparedMap, dataMap));
        b = new BigDecimal(compare(toComparedMap, dataMap1));


        System.out.println(a.toPlainString());
        System.out.println(b.toPlainString());
        System.out.println(a.compareTo(b));
        System.out.println();
*/

        a = new BigDecimal(TextSimilarity.calculateCosineSimilarity(toComparedMap, dataMap));
        b = new BigDecimal(TextSimilarity.calculateCosineSimilarity(toComparedMap, dataMap1));


        System.out.println(a.toPlainString());
        System.out.println(b.toPlainString());
        System.out.println(a.compareTo(b));


    }


}
